/*
                    Pathfinding Header
*/

#ifndef PATHFINDING_H
#define PATHFINDING_H

#include <queue>
#include <vector>
#include <iostream>

#include "Point.h"
#include "Mapping/Map.h"
#include "NetworkDefinitions.h"
#include "Player.h"

using namespace std;

struct Node
    {
        Node(const int& ng, const int& nh, const int& nx, const int& ny)
        {
            // the movement cost to move from the starting point to this node following the path generated to get here
            g = ng;
            // estimated movement cost to get to the end
            h = nh;

            // position
            x = nx;
            y = ny;

            f = g + h;

            bOpen = false;
            bClosed = false;
            ptrParent = NULL;
        }

        void Calculate()
        {
            f = g + h;
        }

        int f, g, h;
        int x, y;
        bool bOpen, bClosed;
        Node *ptrParent;
};

class Pathfinding
{
    public:
        Pathfinding() {}
        ~Pathfinding() {}

        void Initialise(Map& currentMap);
        void Quit();

        // return a vector of directions for the snake to use
        queue<int> GeneratePath(Player *ptrPlayer, Point Start, Point End, int iDirection, vector<Player*>& AvoidList);

    private:
        boost::numeric::ublas::matrix<Node*> NodeMap;
        boost::numeric::ublas::matrix<int> CollisionMatrix;

        int iWidth, iHeight;

        int GetNodeH(int x, int y, const Point& End);

        bool AddNodeToOpenList(boost::numeric::ublas::matrix<int>& m, vector<Node*>& OpenList, int x, int y, Node* Parent, const Point& End);
        void AddNodeToClosedList(vector<Node*>& ClosedList, int x, int y);
};

#endif
